package ynu.edu.dish.service.impl;

import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ynu.edu.common.exception.BusinessException;
import ynu.edu.dish.dto.DishCategoryDTO;
import ynu.edu.dish.entity.DishCategory;
import ynu.edu.dish.repository.DishCategoryRepository;
import ynu.edu.dish.service.DishCategoryService;
import ynu.edu.dish.vo.DishCategoryVO;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 菜品分类服务实现类
 */
@Service
@RequiredArgsConstructor
public class DishCategoryServiceImpl implements DishCategoryService {

    private final DishCategoryRepository dishCategoryRepository;

    @Override
    @Transactional
    public DishCategoryVO createDishCategory(DishCategoryDTO dishCategoryDTO) {
        // 检查同一商家下是否已存在同名分类
        Optional<DishCategory> existingCategory = dishCategoryRepository.findByNameAndMerchantId(
                dishCategoryDTO.getName(), dishCategoryDTO.getMerchantId());
        if (existingCategory.isPresent()) {
            throw new BusinessException("该商家下已存在同名分类");
        }

        // 创建新的菜品分类
        DishCategory dishCategory = new DishCategory();
        BeanUtils.copyProperties(dishCategoryDTO, dishCategory);

        // 保存菜品分类
        dishCategory = dishCategoryRepository.save(dishCategory);

        // 转换为VO并返回
        return convertToVO(dishCategory);
    }

    @Override
    @Transactional
    public DishCategoryVO updateDishCategory(DishCategoryDTO dishCategoryDTO) {
        // 检查菜品分类是否存在
        DishCategory dishCategory = dishCategoryRepository.findById(dishCategoryDTO.getId())
                .orElseThrow(() -> new BusinessException("菜品分类不存在"));

        // 检查同一商家下是否已存在同名分类（排除自身）
        Optional<DishCategory> existingCategory = dishCategoryRepository.findByNameAndMerchantId(
                dishCategoryDTO.getName(), dishCategoryDTO.getMerchantId());
        if (existingCategory.isPresent() && !existingCategory.get().getId().equals(dishCategoryDTO.getId())) {
            throw new BusinessException("该商家下已存在同名分类");
        }

        // 更新菜品分类
        BeanUtils.copyProperties(dishCategoryDTO, dishCategory);

        // 保存菜品分类
        dishCategory = dishCategoryRepository.save(dishCategory);

        // 转换为VO并返回
        return convertToVO(dishCategory);
    }

    @Override
    public DishCategoryVO getDishCategoryById(Long id) {
        // 查询菜品分类
        DishCategory dishCategory = dishCategoryRepository.findById(id)
                .orElseThrow(() -> new BusinessException("菜品分类不存在"));

        // 转换为VO并返回
        return convertToVO(dishCategory);
    }

    @Override
    @Transactional
    public boolean deleteDishCategory(Long id) {
        // 检查菜品分类是否存在
        if (!dishCategoryRepository.existsById(id)) {
            throw new BusinessException("菜品分类不存在");
        }

        // 删除菜品分类
        dishCategoryRepository.deleteById(id);

        return true;
    }

    @Override
    public List<DishCategoryVO> getDishCategoriesByMerchantId(Long merchantId) {
        // 查询菜品分类列表
        List<DishCategory> dishCategories = dishCategoryRepository.findByMerchantId(merchantId);

        // 转换为VO列表并返回
        return dishCategories.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<DishCategoryVO> getDishCategoriesByMerchantIdAndStatus(Long merchantId, Integer status) {
        // 查询菜品分类列表
        List<DishCategory> dishCategories = dishCategoryRepository.findByMerchantIdAndStatus(merchantId, status);

        // 转换为VO列表并返回
        return dishCategories.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public Page<DishCategoryVO> getDishCategoriesByMerchantId(Long merchantId, int page, int size) {
        // 创建分页请求
        PageRequest pageRequest = PageRequest.of(page, size, Sort.by(Sort.Direction.ASC, "sort"));

        // 查询菜品分类分页列表
        Page<DishCategory> dishCategoryPage = dishCategoryRepository.findByMerchantId(merchantId, pageRequest);

        // 转换为VO分页列表并返回
        List<DishCategoryVO> dishCategoryVOs = dishCategoryPage.getContent().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());

        return new PageImpl<>(dishCategoryVOs, pageRequest, dishCategoryPage.getTotalElements());
    }

    @Override
    @Transactional
    public boolean updateDishCategoryStatus(Long id, Integer status) {
        // 检查菜品分类是否存在
        DishCategory dishCategory = dishCategoryRepository.findById(id)
                .orElseThrow(() -> new BusinessException("菜品分类不存在"));

        // 更新状态
        dishCategory.setStatus(status);
        dishCategoryRepository.save(dishCategory);

        return true;
    }

    /**
     * 将实体转换为VO
     *
     * @param dishCategory 菜品分类实体
     * @return 菜品分类VO
     */
    private DishCategoryVO convertToVO(DishCategory dishCategory) {
        DishCategoryVO dishCategoryVO = new DishCategoryVO();
        BeanUtils.copyProperties(dishCategory, dishCategoryVO);
        return dishCategoryVO;
    }
} 